package com.freewater.cargotracker.domain.model.location;

import org.apache.commons.lang3.Validate;

import java.io.Serializable;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * United nations location code.
 * <p/>
 * http://www.unece.org/cefact/locode/
 * http://www.unece.org/cefact/locode/DocColumnDescription.htm#LOCODE
 */
public class UnLocode implements Serializable {

    private static final long serialVersionUID = 1;

    private static final Pattern VALID_PATTERN = Pattern.compile("[a-zA-Z]{2}[a-zA-Z2-9]{3}");

    private String code;

    /**
     * @param countryAndLocation Location string, must math the pattern {@link #VALID_PATTERN}
     */
    public UnLocode(String countryAndLocation) {
        Validate.notNull(countryAndLocation, "Country and location are required");
        Validate.isTrue(VALID_PATTERN.matcher(countryAndLocation).matches(),
                countryAndLocation +
                        "is not a valid UN/LOCODE (does not match the pattern)");

        this.code = countryAndLocation.toUpperCase();
    }

    /**
     * @return country code and location code concatenated, always upper case.
     */
    public String getCode() {
        return this.code;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || this.getClass() != obj.getClass()) {
            return false;
        }
        final UnLocode other = (UnLocode) obj;
        return this.sameValueAs(other);
    }

    @Override
    public int hashCode() {
        return Objects.hash(this.code);
    }

    @Override
    public String toString() {
        return this.code;
    }

    boolean sameValueAs(UnLocode other) {
        return other != null && this.code.equals(other.code);
    }
}
